// 入口文件
import React from 'react'
import ReactDOM from 'react-dom'
// 导入的全局样式
import './index.css'
import App from './App'

// react元素=》根html有啥区别？=>虚拟DOM
const h1 = React.createElement('h1', { className: 'test' }, '你好，react-cli!')
const p = React.createElement('p', null, '我是P元素')
const div = React.createElement('div', null, h1, p)

// JSX => react元素
const test = <div>
  <h1>你好，react-cli!</h1>
  <p>我是P元素</p>
  <ul>
    <li>123</li>
  </ul>
</div>

// 声明式的写UI
const span1 = <span>你好 jsx!</span>
const span2 = React.createElement('span', null, '你好 jsx!')
console.log(span1, span2)
// JSX 使用注意
/**
 * 1. 标签的class=>className
 * 2. 只能有一个根元素
 * 3. 建议用()包裹
 */
// 相当于vue的模版template
// 差值表达式使用
let abc = 10
const div2 = (
  <div className="div1">
    <h2 className="title">我是H2</h2>
    <p>{abc}</p>
  </div>
)
// 差值表达式使用注意和支持的数据类型
// - 单大括号中可以使用任意的 JavaScript 表达式 （值，变量，函数调用，三元运算符，数组(基本类型，jsx)）
// - **JSX 自身也是 JS 表达式** （语法糖：React.createElement()）
// - 注意：不能在{}中出现语句和对象（比如：if/for，{a:100} 等） 
let a = 'string', b = false
let arr = [1, 2, 3, 10]
let obj = { a: 1, b: 2 }
let fn = () => {
  return '我是一个方法'
}
function fn2 () {
  return <span>100</span>
}
const div3 = (
  <div>
    <h1>{100000}</h1>
    <h2>{a}</h2>
    <p>{b ? '1' : '2'}</p>
    <ul>
      <li>{fn()}</li>
      <li>{fn2()}</li>
      <li><span>1</span></li>
      <li>{<span>2</span>}</li>
      <li>{arr}</li>
      {/* <li>{obj}</li> */}
      <li>{obj.a},{obj.b}</li>
    </ul>
  </div>
)

/**
 * 模版渲染
 */
// 1. 条件渲染
// ajax请求：请求开始=》显示loading...=>关闭loading效果
let loaded = true
// 方法
/**
 * 
 * @param {*} loaded 数据是否加载完成
 */
let fn4 = (loaded) => {
  if (loaded) {
    return <span className="black">加载完成了！</span>
  } else {
    return <span className="red">加载中...</span>
  }
}
const div4 = (
  <div>
    <h1>{loaded ? <span className="black">加载完成了！</span> : <span className="red">加载中...</span>}</h1>
    <h2>{fn4(false)}</h2>
  </div>
)

// 列表渲染
// 使用数组的map方法遍历数据=》返回新数据（数组的项=》列表项的模版）
// 举例：这是ajax请求获取的数据
const songs = [
  { id: 1, name: '野狼disco', bg: 'red' },
  { id: 2, name: '像我这样的人', bg: 'orange' },
  { id: 3, name: '桥边姑娘', bg: 'blue' },
]

const div5 = (
  <ul className="ul1">
    {/* {[<li>1</li>, <li>2</li>]} */}
    {songs.map((item) => {
      return <li style={{ backgroundColor: item.bg, fontSize: '24px' }} key={item.id}>{item.name}</li>
    })}
  </ul>
)

// 组件创建
// 1. 函数组件：
// - 函数组件：使用 JS 的函数（或箭头函数）创建的组件 
//   - 函数体内要返回元素（jsx）
// - 渲染函数组件：用函数名作为**组件标签名** 
let Fnc = () => {

  // vue=》script 交互
  let a = '我是函数组件'

  // vue=》template 模版
  return (
    <div>
      <h1>{a}</h1>
      <Fnc2></Fnc2>
      <hr />
      <Fnc2 />
      <hr />
      <ClaCom />
    </div>
  )
}

function Fnc2 (params) {
  return <div>
    <h3>我是函数组件2</h3>
  </div>
}

/**
 * 类组件：
 * ##### 语法

- 类组件：使用 **ES6 的 class关键字** 创建的组件 
- 类组件应该继承 React.Component 父类，从而可以使用父类中提供的方法和属性  
- 类里边实现父类提供的render()，返回一个模版
 */

class ClaCom extends React.Component {
  // js交互
  a = 10
  // 模版
  render () {
    return (
      <div>
        <h1>我是类组件</h1>
        <p>{this.a}</p>
      </div>
    )
  }
}



ReactDOM.render(
  <App />,
  document.getElementById('root')
)

